package com.c0der.neat;

import java.util.Random;

public class Config {
    public static final Random rand = new Random();
    public final int inputs, outputs;
    public final double newNodeRate;
    public final double newConnectionRate;
    public final double ableConnectionRate;
    public final double weightRate;
    public final double weightMax;
    public final double weightMin;
    public final double biasRate;
    public final double biasMax;
    public final double biasMin;

    public Config(
            int inputs, int outputs,
            double newNodeRate,
            double newConnectionRate,
            double ableConnectionRate,
            double weightRate,
            double weightMax,
            double weightMin,
            double biasRate,
            double biasMax,
            double biasMin) {
        this.inputs = inputs;
        this.outputs = outputs;
        this.newNodeRate = newNodeRate;
        this.newConnectionRate = newConnectionRate;
        this.ableConnectionRate = ableConnectionRate;
        this.weightRate = weightRate;
        this.weightMax = weightMax;
        this.weightMin = weightMin;
        this.biasRate = biasRate;
        this.biasMax = biasMax;
        this.biasMin = biasMin;
    }

    private final double random() {
        return rand.nextDouble();
    }

    public final double weight(double old) {
        if (random() >= weightRate)
            return old;
        double w = random() * (weightMax - weightMin) + weightMin;
        if (w < weightMin)
            w = weightMin;
        if (w > weightMax)
            w = weightMax;
        return w;
    }

    public final double bias(double old) {
        if (random() >= biasRate)
            return old;
        double b = random() * (biasMax - biasMin) + biasMin;
        if (b < biasMin)
            b = biasMin;
        if (b > biasMax)
            b = biasMax;
        return b;
    }

    public final boolean newNode() {
        return random() < newNodeRate;
    }

    public final boolean newConnection() {
        return random() < newConnectionRate;
    }


    public final boolean able(boolean old) {
        return random() < ableConnectionRate ? !old : old;
    }
}
